package auctiongui;

import auctioncentral.AuCenStaffUser;
import auctioncentral.AuctionSystem;
import auctioncentral.BiddingUser;
import auctioncentral.Event;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.LinkedList;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;

/**
 * this class handles the Calender popup for the program.
 * @author Kris
 * @version 3/8/2014
 */
public class CalendarPanel extends JPanel {

  /***/
  private JLabel my_month_label, my_year_label;
  /***/
  private JButton my_prev, my_next;
  /***/
  private JTable my_table_calendar;
  /***/
  private JComboBox my_year_box;
  /***/
  private JPanel my_frame;
  /****/
  private DefaultTableModel mtblCalendar; //Table model
  /****/
  private JScrollPane stblCalendar; //The scrollpane
  /***/
  private JPanel calendar_panel;
  /***/
  private int realYear, realMonth, realDay, currentYear, currentMonth;
  /***/
  private List<Event> my_events = new LinkedList<Event>(){};
  /***/
  private AuctionSystem my_system;
  /***/
  private JList my_auctions;
  private MouseAdapter my_mouse;
  
  /**
   * 
   * @param the_system
   */
  public CalendarPanel(AuctionSystem the_system) {
	super();
	my_system = the_system;
	my_events = my_system.getEventList();

    try {UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());}
    catch (ClassNotFoundException e) {}
    catch (InstantiationException e) {}
    catch (IllegalAccessException e) {}
    catch (UnsupportedLookAndFeelException e) {}
        my_frame = new JPanel (); //Create frame
//        my_frame.setPreferredSize(new Dimension(1000, 1000)); //Set size to 400x400 pixels
        setLayout(new BorderLayout()); //Apply null layout
        
        //Create controls
        my_month_label = new JLabel ("January");
        my_year_label = new JLabel ("Change year:");
        my_year_box = new JComboBox();
        my_prev = new JButton ("<<");
        my_next = new JButton (">>");
        mtblCalendar = new DefaultTableModel()
          {public boolean isCellEditable(int rowIndex, int mColIndex){return false;}};
//          mtblCalendar.
        my_table_calendar = new JTable(mtblCalendar);
//        my_table_calendar.setSelectionMode(selectionMode)
        stblCalendar = new JScrollPane(my_table_calendar);
        calendar_panel = new JPanel(null);
        
        
        String[] my_auction_buttons = new String[my_events.size()];
        for (int i = 0; i < my_events.size(); i++) {
        	my_auction_buttons[i] = my_events.get(i).getName(); 
        }
        JScrollPane newPane = new JScrollPane();
        newPane.setVisible(true);
        newPane.setBounds(0, 450, 600, 100);
        my_auctions = new JList(my_auction_buttons);
        my_auctions.addMouseListener(new MouseAdapter() {
        	public void mouseClicked(MouseEvent the_e) {
        		if (the_e.getClickCount() == 2) {
        			String selectedItem = (String) my_auctions.getSelectedValue();
        			Event the_event = my_system.findEventFromName(selectedItem);
        			if (the_event != null && (the_event.getUser().equals(my_system.getMy_current_user().getName()) || my_system.getMy_current_user() instanceof AuCenStaffUser||my_system.getMy_current_user() instanceof BiddingUser)) {
        				
            			new NewEvent(my_system, my_system.getMy_current_user(), my_system.findEventFromName(selectedItem)).setVisible(true);
        			} else {
        		        JOptionPane.showMessageDialog(null, "An Error has occurred. Please Try Again.", "We're Sorry", JOptionPane.ERROR_MESSAGE);
        			}
        		}
        	}
        });
        my_auctions.setBounds(0, 450, 600, 100);
        newPane.setViewportView(my_auctions);
        //Set border
        calendar_panel.setBorder(BorderFactory.createTitledBorder("Calendar"));
        //Register action listeners
        my_prev.addActionListener(new btnPrev_Action());
        my_next.addActionListener(new NextAction());
        my_year_box.addActionListener(new YearAction());
        //Add controls to pane
//        my_auctions.setBackground(Color.BLUE);
        add(newPane);
        add(calendar_panel);

        calendar_panel.add(my_month_label);
        calendar_panel.add(my_year_label);
        calendar_panel.add(my_year_box);
        calendar_panel.add(my_prev);
        calendar_panel.add(my_next);
        calendar_panel.add(stblCalendar);
        //Set bounds
        /********/
       
        /********/
        calendar_panel.setBounds(0, 0, 600, 400);
        my_month_label.setBounds(600, 25, 100, 25);
        my_year_label.setBounds(190, 305, 80, 20);
        my_year_box.setBounds(260, 305, 80, 20);
        my_prev.setBounds(10, 25, 50, 25);
        my_next.setBounds(540, 25, 50, 25);
        stblCalendar.setBounds(10, 50, 580, 330);
        //Make frame visible
//        my_frame.setVisible(false);
        my_frame.setVisible(true);
//       / //Get real month/year
        GregorianCalendar cal = new GregorianCalendar(); //Create calendar
        realDay = cal.get(GregorianCalendar.DAY_OF_MONTH); //Get day
        realMonth = cal.get(GregorianCalendar.MONTH); //Get month
        realYear = cal.get(GregorianCalendar.YEAR); //Get year
        currentMonth = realMonth; //Match month and year
        currentYear = realYear;
        //Add headers
        String[] headers = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; //All headers
        for (int i=0; i<7; i++){
            mtblCalendar.addColumn(headers[i]);
        }
        my_table_calendar.getParent().setBackground(my_table_calendar.getBackground()); //Set background
        //No resize/reorder
        my_table_calendar.getTableHeader().setResizingAllowed(false);
        my_table_calendar.getTableHeader().setReorderingAllowed(false);
        //Single cell selection
        my_table_calendar.setColumnSelectionAllowed(true);
        my_table_calendar.setRowSelectionAllowed(true);
        my_table_calendar.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        //Set row/column count
        my_table_calendar.setRowHeight(38);
        mtblCalendar.setColumnCount(7);
        mtblCalendar.setRowCount(6);
        //Populate table
        for (int i=realYear-100; i<=realYear+100; i++){
            my_year_box.addItem(String.valueOf(i));
        }
        //Refresh calendar
        refreshCalendar (realMonth, realYear); //Refresh calendar
        
       
    }
  
 
  
  
  /**
   * 
   * @param month
   * @param year
   */
    public void refreshCalendar(int month, int year) {
        //Variables
        String[] months =  {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
        int nod, som; //Number Of Days, Start Of Month
        //Allow/disallow buttons
        my_prev.setEnabled(true);
        my_next.setEnabled(true);
        if (month == 0 && year <= realYear-10){my_prev.setEnabled(false);} //Too early
        if (month == 11 && year >= realYear+100){my_next.setEnabled(false);} //Too late
        my_month_label.setText(months[month]); //Refresh the month label (at the top)
        my_month_label.setBounds(160-my_month_label.getPreferredSize().width/2, 25, 180, 25); //Re-align label with calendar
        my_year_box.setSelectedItem(String.valueOf(year)); //Select the correct year in the combo box
        //Clear table
        for (int i=0; i<6; i++){
            for (int j=0; j<7; j++){
                mtblCalendar.setValueAt(null, i, j);
            }
        }
        //Get first day of month and number of days
        GregorianCalendar cal = new GregorianCalendar(year, month, 1);
        nod = cal.getActualMaximum(GregorianCalendar.DAY_OF_MONTH);
        som = cal.get(GregorianCalendar.DAY_OF_WEEK);
        
        List<Event> temp_list = new LinkedList<Event>();
        for(Event blah : my_events)
        {
          if(blah.getDate().get(Calendar.YEAR) == year && 
        		  blah.getDate().get(Calendar.MONTH) == month)
          {
        	  temp_list.add(blah);
          }
        }
        
        //Draw calendar
        for (int i=1; i<=nod; i++){
            int row = new Integer((i+som-2)/7);
            int column  =  (i+som-2)%7;
            mtblCalendar.setValueAt(i, row, column);
        }
        //Apply renderers
        my_table_calendar.setDefaultRenderer(my_table_calendar.getColumnClass(0), new tblCalendarRenderer(temp_list));
        my_table_calendar.removeMouseListener(my_mouse);
		  my_mouse = new MouseAdapter() {
			public void mouseClicked(MouseEvent e) {
				if (e.getClickCount() == 2) {
					JTable target = (JTable) e.getSource();
					int row1 = target.getSelectedRow();
					int column1 = target.getSelectedColumn();
					boolean changed = false;
					for (Event temp : my_events) {
						if (temp.getDate().get(Calendar.DAY_OF_MONTH) == (Integer)my_table_calendar.getValueAt(row1, column1) && temp.getDate().get(Calendar.MONTH) == currentMonth && temp.getDate().get(Calendar.YEAR) == currentYear && 
								((temp.getUser().equals(my_system.getMy_current_user().getName())) || my_system.getMy_current_user() instanceof AuCenStaffUser || my_system.getMy_current_user() instanceof BiddingUser)) {
							new NewEvent(my_system, my_system.getMy_current_user(), my_system.getEventList().get(my_events.indexOf(temp))).setVisible(true);
							changed = true;
						}
					}
					if (!changed && !(my_system.getMy_current_user() instanceof BiddingUser)) {
						new NewEvent(my_system, new GregorianCalendar(currentYear, currentMonth, (Integer)my_table_calendar.getValueAt(row1, column1))).setVisible(true);
					}
					// do some action if appropriate column
				}
			}
		  };
			my_table_calendar.addMouseListener(my_mouse);

    }
 
    /**
     * 
     * @author Kris
     *
     */
    private class tblCalendarRenderer extends DefaultTableCellRenderer {
    	private List<Event> my_event_list;
    	tblCalendarRenderer(List<Event> the_events)
    	{
    	  my_event_list = the_events;
    	}
        public Component getTableCellRendererComponent 
          (JTable table, Object value, boolean selected, boolean focused, int row, int column){
            super.getTableCellRendererComponent(table, value, selected, focused, row, column);
            
            if (column == 0 || column == 6){ //Week-end
                setBackground(new Color(255, 220, 220));
            }
            else { //Week
                setBackground(new Color(255, 255, 255));
//                setText("fuckityfuck");
            }
            if (value != null){
                if (Integer.parseInt(value.toString()) == realDay && currentMonth == realMonth && currentYear == realYear){ //Today
                    setBackground(new Color(220, 220, 255));
                }
            }
            if(!my_event_list.isEmpty() && value!=null)
            {
                for (Event temp : my_event_list)
                {
                  if (temp.getDate().get(Calendar.DAY_OF_MONTH) == (Integer) value)
                  {
                  	setBackground(Color.GREEN);
                  	setText(temp.getName());
                  	add(temp.getName(), new JButton());
                  }
                }
            }
            
            setBorder(null); 
            setForeground(Color.black);
            return this; 
        }
    }
    
    /*
     * 
     */
    private class btnPrev_Action implements ActionListener {
        public void actionPerformed (ActionEvent e){
            if (currentMonth == 0){ //Back one year
                currentMonth = 11;
                currentYear -= 1;
            }
            else{ //Back one month
                currentMonth -= 1;
            }
            refreshCalendar(currentMonth, currentYear);
        }
    }
    
    /**
     * 
     * @author Kris
     *
     */
    private class NextAction implements ActionListener {

       public void actionPerformed (ActionEvent e){
            if (currentMonth == 11){ //Foward one year

                currentMonth = 0;

                currentYear += 1;

            }

            else{ //Foward one month

                currentMonth += 1;

            }

            refreshCalendar(currentMonth, currentYear);

        }

    }

    /**
     * 
     * @author Kris
     *
     */
  private class YearAction implements ActionListener {
    public void actionPerformed (ActionEvent e){
    if (my_year_box.getSelectedItem() != null){
    String b = my_year_box.getSelectedItem().toString();

    currentYear = Integer.parseInt(b);

    refreshCalendar(currentMonth, currentYear);

    }

  }
  }
  
  /**
   * 
   * @author Kris
   *
   */
  private class ViewEventAction implements ActionListener {
	    public void actionPerformed (ActionEvent e){
	    if (my_year_box.getSelectedItem() != null){
	    String b = my_year_box.getSelectedItem().toString();

	    currentYear = Integer.parseInt(b);

	    refreshCalendar(currentMonth, currentYear);

	    }

	  }
	  }

}
